package com.google.code.coma.gui.dialog;

import com.google.code.coma.domain.Type;
import com.google.code.coma.gui.worker.WorkerManager;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

/**
 * @author Dominik Strasser, dominikstr@gmail.com
 */
public class ProducerConfigurationDialog extends Stage {
	private int amount = 0;

	private Type type = Type.CPU;

	private int faultRate = 0;

	public ProducerConfigurationDialog(final WorkerManager.Mode operationMode, final String factoryId) {
		super();
		initModality(Modality.APPLICATION_MODAL);
		initStyle(StageStyle.UTILITY);
		setTitle("Create Producer");
		setWidth(250);
		setHeight(180);

		GridPane grid = new GridPane();
		grid.setPadding(new Insets(10, 10, 10, 10));
		grid.setVgap(5);
		grid.setHgap(5);
		grid.setStyle("-fx-background-color: DAE6F3");

		final Button okButton = new Button("Create");
		okButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent actionEvent) {
				WorkerManager.createWorker(WorkerManager.WorkerType.PRODUCTION, operationMode, factoryId, amount, type, faultRate);
				ProducerConfigurationDialog.this.close();
			}
		});

		Label amountLabel = new Label("Amount: ");
		GridPane.setConstraints(amountLabel, 0, 0);
		grid.getChildren().add(amountLabel);
		final TextField amountField = new TextField("" + amount);
		amountField.textProperty().addListener(new ChangeListener<String>() {
			@Override
			public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) {
				try {
					amount = Integer.parseInt(newValue);
					if (amount < 1) throw new NumberFormatException();
					okButton.setDisable(false);
				} catch (Exception e) {
					okButton.setDisable(true);
				}
			}
		});
		GridPane.setConstraints(amountField, 1, 0);
		grid.getChildren().add(amountField);
		Label typeLabel = new Label("Type: ");
		GridPane.setConstraints(typeLabel, 0, 1);
		grid.getChildren().add(typeLabel);
		ChoiceBox typeCB = new ChoiceBox<Type>(FXCollections.observableArrayList(Type.values()));
		typeCB.getSelectionModel().select(Type.CPU);
		typeCB.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Type>() {
			@Override
			public void changed(ObservableValue<? extends Type> observableValue, Type oldValue, Type newValue) {
				ProducerConfigurationDialog.this.type = newValue;
			}
		});
		GridPane.setConstraints(typeCB, 1, 1);
		grid.getChildren().add(typeCB);
		Label rateLabel = new Label("Fault rate: ");
		GridPane.setConstraints(rateLabel, 0, 2);
		grid.getChildren().add(rateLabel);
		final Label rateValue = new Label("" + faultRate);
		Slider slider = new Slider();
		slider.setMin(0);
		slider.setMax(100);
		slider.setValue(0);
		slider.setShowTickLabels(true);
		slider.setShowTickMarks(true);
		slider.setMajorTickUnit(50);
		slider.setMinorTickCount(5);
		slider.setBlockIncrement(10);
		slider.valueProperty().addListener(new ChangeListener<Number>() {
			public void changed(ObservableValue<? extends Number> ov,
								Number old_val, Number new_val) {
				faultRate = new_val.intValue();
				rateValue.setText("" + faultRate);
			}
		});
		HBox box = new HBox();
		box.getChildren().addAll(slider, rateValue);
		GridPane.setConstraints(box, 1, 2);
		grid.getChildren().add(box);

		GridPane.setConstraints(okButton, 1, 3);
		grid.getChildren().add(okButton);

		Scene scene = new Scene(grid);
		setScene(scene);
	}

	public int getAmount() {
		return amount;
	}

	public Type getType() {
		return type;
	}

	public int getFaultRate() {
		return faultRate;
	}
}
